package com.gitee.apanlh.util.valid;

import com.gitee.apanlh.util.net.addr.IpUtils;

import java.util.regex.Pattern;

/**	
 * 	正则表达式验证工具类
 * 
 * 	@author Pan
 */
public class RegexUtils {
	
	/** 手机正则表达式  <br>验证手机号码包含 13 14 15 16 17 18 19*/
	//private static final Pattern P_PHONE_REG = Pattern.compile("^(0|86|17951)*(13[0-9]|14[57]|15[0-9]|16[0-9]|17[0-8]|18[0-9]|19[0-9])[0-9]{8}$");
	private static final Pattern P_PHONE_REG = Pattern.compile("^(13[0-9]|14[57]|15[0-9]|16[0-9]|17[0-8]|18[0-9]|19[0-9])[0-9]{8}$");
	/** 验证是否为 数字 */
	private static final Pattern P_NUMBER_REG = Pattern.compile("[0-9]*");
	/** 验证是否为 英文字母 */
	private static final Pattern P_ENGLISH_REG = Pattern.compile("^[A-Za-z]+$");
	/** 验证 包含字母-数字 */
	private static final Pattern P_NUM_ENGLISH_REG = Pattern.compile("^[A-Za-z0-9]+$");
	/** 验证包含 字母-数字-下划线 加 横杆（-） */
	private static final Pattern P_NUM_ENGLISH_LINE_REG_TAG = Pattern.compile("^[A-Za-z0-9_-]+$");
	/** 验证包含 字母-数字-下划线 */
	private static final Pattern P_NUM_ENGLISH_LINE_REG = Pattern.compile("^[A-Za-z0-9_]+$");
	/** 验证是否为 邮政编码 */
	private static final Pattern P_POSTAL_CODE_REG = Pattern.compile("[1-9]\\d{5}(?!\\d)");
	/** 验证是否为 URL地址 */
	private static final Pattern P_URL_REG = Pattern.compile(
						"^((https|http|ftp|rtsp|mms)?://)" 
				.concat("(([0-9a-z_!~*'().&=+$%-]+: )?[0-9a-z_!~*'().&=+$%-]+@)?") 
				.concat("(([0-9]{1,3}\\.) {3}[0-9]{1,3}|")
				.concat("([0-9a-z_!~*'()-]+\\.)*")
				.concat("([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\\.[a-z]{2,6})")
				.concat("(:[0-9]{1,4})?((/?)|")
				.concat("(/[0-9a-z_!~*'().;?:@&=+$,%#-]+)+/?)$")
	);
	/** 验证	浮点型 */
	private static final Pattern P_FLOAT_REG = Pattern.compile("^\\d+(\\.\\d+)?$");
	/** 验证是否为中文 */
	private static final Pattern P_CHINESE_REG = Pattern.compile("^[\\u4E00-\\u9FA5]+$");
	/** 验证图片后缀 <br>bmp、jpg、png、gif、JPEG、jpeg、 */
	private static final Pattern P_IMAGE_REG = Pattern.compile(".+(.JPEG|.jpeg|.JPG|.jpg|.bmp|.BMP|.gif|.GIF|.png|.PNG)$");
	/** 验证十六进制字符串 */
	private static final Pattern P_HEX_REG = Pattern.compile("^[a-f0-9A-F]+$");
//	/** 验证是否为正确的邮箱 */
	//private static final Pattern P_EMAIL_REG = Pattern.compile("^([a-zA-Z]|[0-9])(\\w|\\-)+@[a-zA-Z0-9]+\\.([a-zA-Z]{2,4})$");
	/** 格式为[用户名@域名.顶级域名]的邮件地址，其中用户名部分至少包含3个字符，最多包含18个字符，域名和顶级域名部分可以包含字母、数字、下划线、连字符和句点 */
	private static final Pattern P_EMAIL_REG = Pattern.compile("^(\\w+([-.][A-Za-z0-9]+)*){3,18}@\\w+([-.][A-Za-z0-9]+)*\\.\\w+([-.][A-Za-z0-9]+)*$");
	/** 强密码校验 <br>必须包含 大写、小写、数字、特殊字符 8-20位组成的密码 */
	private static final Pattern P_FIRST_STRONG_PASSWORD = Pattern.compile("^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*().,]).{8,20}$");
	/** 强密码校验 <br>必须包含 大小写字母、数字、特殊字符 8-20位组成的密码 */
	private static final Pattern P_SECOND_STRONG_PASSWORD = Pattern.compile("^(?=.*\\d)(?=.*[a-zA-Z])(?=.*[!@#$%^&*().,]).{8,20}$");
	
	/**
	 * 	构造函数
	 * 
	 * 	@author Pan
	 */
	private RegexUtils() {
		//	不允许外部实例
		super();
	}
	
	/**	
	 * 	判断是否属于十六进制字符串
	 * 	
	 * 	@author Pan
	 * 	@param  content	 内容
	 * 	@return	boolean
	 */
	public static boolean isHex(String content) {
		if (ValidParam.isEmpty(content)) {
			return false;
		}
		return P_HEX_REG.matcher(content).matches();
	}
	
	/**	
	 * 	功能：验证手机号码为 13 14 15 16 17 18 19
	 * 	<br>判断手机号码是否正确
	 * 	
	 * 	@author Pan
     * 	@param  phone 手机号
     * 	@return	boolean true为正确匹配 | false不正确匹配
     */
    public static boolean isPhone(String phone) {
		if (ValidParam.isEmpty(phone)) {
			return false;
		}
    	int minLength = 11;
    	
    	if (phone.length() != minLength) {
    		return false;
    	}
        return P_PHONE_REG.matcher(phone).matches();
    }
    
    /**
	 * 	功能：判断字符串是否为数字
	 * 	
	 *	@author Pan
	 * 	@param  str	需要判断的字符
	 * 	@return	boolean true为正确匹配 | false不正确匹配
	 */
	public static boolean isNumeric(String str) {
		if (ValidParam.isEmpty(str)) {
			return false;
		}
		return P_NUMBER_REG.matcher(str).matches();
	}
	
	/**	
	 * 	功能：验证是否为浮点型
	 * 	
	 * 	@author Pan
	 * 	@param  floatVal 浮点字符串
	 * 	@return	boolean
	 */
	public static boolean isFloat(String floatVal) {
		if (ValidParam.isEmpty(floatVal)) {
			return false;
		}
		return P_FLOAT_REG.matcher(floatVal).matches();
	}
	
	/**	
	 * 	功能：验证 英文字母
	 * 	
	 * 	@author Pan
	 * 	@param  str 字符串
	 * 	@return	boolean
	 */
	public static boolean isEnglish(String str) {
		if (ValidParam.isEmpty(str)) {
			return false;
		}
		return P_ENGLISH_REG.matcher(str).matches();
	}
	
	/**	
	 * 	功能：验证是否包含了英文-数字	
	 * 
	 * 	@author Pan
	 * 	@param  str 字符串
	 * 	@return	boolean
	 */
	public static boolean isNumEnglish(String str) {
		if (ValidParam.isEmpty(str)) {
			return false;
		}
		return P_NUM_ENGLISH_REG.matcher(str).matches();
	}
	
	/**	
	 * 	功能：验证包含 英文字母-数字-下划线
	 * 	
	 * 	@author Pan
	 * 	@param  str 字符串
	 * 	@return	boolean
	 */
	public static boolean isNumEnglishLine(String str) {
		if (ValidParam.isEmpty(str)) {
			return false;
		}
		return P_NUM_ENGLISH_LINE_REG.matcher(str).matches();
	}
	
	/**	
	 * 	功能：验证包含 英文字母-数字-下划线 横杆-
	 * 	
	 * 	@author Pan
	 * 	@param  str 字符串
	 * 	@return	boolean
	 */
	public static boolean isNumEnglishLineTag(String str) {
		if (ValidParam.isEmpty(str)) {
			return false;
		}
		return P_NUM_ENGLISH_LINE_REG_TAG.matcher(str).matches();
	}
	
	/**	
	 * 	功能：验证IPV4地址
	 * 
	 * 	@author Pan
	 * 	@param  ipAddress	ip地址
	 * 	@return	boolean
	 */
	public static boolean isIpV4(String ipAddress) {
		if (ValidParam.isEmpty(ipAddress)) {
			return false;
		}
        return IpUtils.isIpV4(ipAddress);
    }
	
	/**	
	 * 	功能：验证是否是邮政编码
	 * 	
	 * 	@author Pan
	 * 	@param  code 邮政编码
	 * 	@return	boolean
	 */
	public static boolean isPostalCode(Long code) {
		if (ValidParam.isNull(code)) {
			return false;
		}
		return P_POSTAL_CODE_REG.matcher(String.valueOf(code)).matches();
	}
	
	/**	
	 * 	功能：验证是否是邮政编码
	 * 	
	 * 	@author Pan
	 * 	@param  code 邮政编码
	 * 	@return	boolean
	 */
	public static boolean isPostalCode(Integer code) {
		if (ValidParam.isNull(code)) {
			return false;
		}
		return P_POSTAL_CODE_REG.matcher(String.valueOf(code)).matches();
	}
	
	/**	
	 * 	功能：验证是否是邮政编码
	 * 	
	 * 	@author Pan
	 * 	@param  code 邮政编码
	 * 	@return	boolean
	 */
	public static boolean isPostalCode(String code) {
		if (ValidParam.isEmpty(code)) {
			return false;
		}
		return P_POSTAL_CODE_REG.matcher(String.valueOf(code)).matches();
	}
	
	/**
	 * 	功能：验证15或18位身份证号
	 *  
	 * 	@author Pan
	 * 	@param  idcard	身份证号
	 * 	@return	boolean
	 */
	public static boolean isIdcard(String idcard) {
		return IdcardUtils.valid(idcard);
	}
	
	/**
	 * 	功能：验证15位身份证	
	 *  
	 * 	@author Pan
	 * 	@param  idcard	身份证号
	 * 	@return boolean
	 */
	public static boolean isIdcard15(String idcard) {
		return IdcardUtils.valid15(idcard);
	}

	/**	
	 * 	功能：验证18位身份证
	 * 
	 * 	@author Pan
	 * 	@param  idcard	身份证号
	 * 	@return	boolean
	 */
	public static boolean isIdcard18(String idcard) {
		return IdcardUtils.valid18(idcard);
	}
	
	/**	
	 * 	功能：验证是否为正常的url
	 * 	
	 * 	@author Pan
	 * 	@param  url url
	 * 	@return	boolean
	 */
	public static boolean isUrl(String url) {
		if (ValidParam.isEmpty(url)) {
			return false;
		}
		return P_URL_REG.matcher(url).matches();
	}
	
	/**	
	 * 	功能：验证字符串是否包含中文
	 * 	
	 * 	@author Pan
	 * 	@param  str 字符串
	 * 	@return	boolean
	 */
	public static boolean isChinese(String str) {
		if (ValidParam.isEmpty(str)) {
			return false;
		}
		return P_CHINESE_REG.matcher(str).matches();
	}
	
	/**	
	 * 	功能： 验证图片后缀名是否正确
	 * 	<br>JPEG|.jpeg|.JPG|.jpg|.bmp|.BMP|.gif|.GIF|.png|.PNG
	 * 	
	 * 	@author Pan
	 * 	@param  name 后缀名称
	 * 	@return	boolean
	 */
	public static boolean isImage(String name) {
		if (ValidParam.isEmpty(name)) {
			return false;
		}
		return P_IMAGE_REG.matcher(name).matches();
	}
	
	/**	
	 * 	验证是否为正确的邮箱
	 * 	
	 * 	@author Pan
	 * 	@param  eMail 邮箱
	 * 	@return	boolean
	 */
	public static boolean isEmail(String eMail) {
		if (ValidParam.isEmpty(eMail)) {
			return false;
		}
		return P_EMAIL_REG.matcher(eMail).matches();
	}
	
	/**	
	 * 	必须包含:大写、小写、数字、特殊字符 8-20位组成的密码
	 * 	
	 * 	@author Pan
	 * 	@param 	pwd 密码
	 * 	@return	boolean
	 */
	public static boolean isStrongPwd(String pwd) {
		if (ValidParam.isEmpty(pwd)) {
			return false;
		}
		return P_FIRST_STRONG_PASSWORD.matcher(pwd).matches();
	}
	
	/**	
	 * 	必须包含:大写或小写字母、数字、特殊字符 8-20位组成的密码
	 * 	
	 * 	@author Pan
	 * 	@param 	pwd 密码
	 * 	@return	boolean
	 */
	public static boolean isSecondStrongPwd(String pwd) {
		if (ValidParam.isEmpty(pwd)) {
			return false;
		}
		return P_SECOND_STRONG_PASSWORD.matcher(pwd).matches();
	}
}
